package dofix;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.xcity.db.entity.Config;

import naga.x.util.CommonUtils;

/**
 * 给老玩家分配坐标
 * @author yang.li
 *
 */
public class PlayerXYFix {

	public static void main(String[] args) {
		if (args == null || args.length < 3) {
			args = new String[] {
					"101.200.172.11/city1.0",
					"root",
					"ly.06360111"
			};
		}
		String url = args[0];
//		jdbc:mysql://rdsd09ffm5143cy22qd4.mysql.rds.aliyuncs.com:3306/platform?characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
		if (!url.startsWith("jdbc:")) {
			url = "jdbc:mysql://" + url + "?characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true";
		}
		String user = args[1];
		String password = args[2];
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, user, password);
			doFix(conn);
			doneFix(conn);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	static void doFix(Connection conn) throws Exception {
		// 查询总玩家数量
		PreparedStatement ps = conn.prepareStatement("select count(id) from player");
		ResultSet rs = ps.executeQuery();
		int count = 0;
		if (rs.next()) {
			count = rs.getInt(1);
		}
		rs.close();
		ps.close();
		System.out.println("try fix: " + count);
		
		// 查询所有玩家并分配坐标
		int offset = 0;
		while (count > 0) {
			int rows = count > 1000 ? 1000 : count;
			ps = conn.prepareStatement("select id from player limit ?, ?");
			ps.setInt(1, offset);
			ps.setInt(2, rows);
			rs = ps.executeQuery();
			
			PreparedStatement ps2 = conn.prepareStatement("update player set map = ?, x = ?, y = ? where id = ?");
			while (rs.next()) {
				long id = rs.getLong(1);
				
				int[] pos = nextPos();
				int map = pos[0];
				int x = pos[1];
				int y = pos[2];
				ps2.setInt(1, map);
				ps2.setInt(2, x);
				ps2.setInt(3, y);
				ps2.setLong(4, id);
				ps2.addBatch();
			}
			int[] n = ps2.executeBatch();
			ps2.close();
			System.out.println("batch fixed: " + (n != null ? n.length : 0));
			
			rs.close();
			ps.close();
			
			offset += rows;
			count -= rows;
		}
		
		
	}
	
	static void doneFix(Connection conn) throws Exception {
		System.out.println("mapIndex=" + mapIndex);
		System.out.println("availablePoints=" + mapAvailablePoints);
		PreparedStatement ps = conn.prepareStatement("insert into config values(?, ?)");
		ps.setString(1, Config.KEY_MAP_INDEX);
		ps.setString(2, String.valueOf(mapIndex));
		ps.addBatch();
		
		ps.setString(1, Config.KEY_MAP_AVAILABLE_POINTS);
		ps.setString(2, JSON.toJSONString(mapAvailablePoints));
		ps.addBatch();
		int[] n = ps.executeBatch();
		System.out.println("config saved: " + (n != null ? n.length : 0));
	}
	
	// 玩家坐标点（客户端）
	static int[][] pos = {
			{ 1207, 2 },  { 1407, 3 }, { 741, 5 }, { 940, 5 }, { 241, 46 }, { 1308, 56 }, { 842, 60 }, { 1054, 66 },
			{ 1531, 71 }, { 955, 123 }, { 93, 126 }, { 1433, 129 }, { 1532, 186 }, { 231, 219 }, { 720, 255 }, { 132, 275 },
			{ 331, 277 }, { 1366, 288 }, { 620, 310 }, { 818, 312 }, { 233, 332 }, { 1266, 343 }, { 1465, 344 }, { 720, 368 },
			{ 1365, 401 }, { 110, 448 }, { 1072, 455 }, { 12, 505 }, { 210, 506 }, { 972, 511 }, { 1170, 513 }, { 113, 561 },
			{ 309, 563 }, { 1073, 568 }, { 825, 595 }, { 727, 652 }, { 926, 652 }, { 288, 704 }, { 827, 708 }, { 515, 719 },
			{ 31, 740 }, { 1087, 745 }, { 414, 776 }, { 614, 777 }, { 1468, 796 }, { 132, 797 }, { 988, 800 }, { 1185, 800 },
			{ 515, 833 }, { 32, 852 }, { 1086, 856 }, { 10, 1007 }, { 605, 1020 }, { 1076, 1020 }, { 108, 1065 }, { 1446, 1065 },
			{ 703, 1075 }, { 977, 1075 }, { 504, 1077 }, { 1177, 1077 }, { 9, 1119 }, { 1076, 1133 }, { 603, 1136 }, { 242, 1142 },
			{ 1306, 1151 }, { 840, 1157 }, { 342, 1198 }, { 142, 1199 }
	};
	private static List<Integer> newMapPoints() {
		int len = pos.length;
		List<Integer> points = new ArrayList<Integer>(len);
		for (int i = 0; i < len; i++) {
			points.add(i);
		}
		return points;
	}
	
	static List<Integer> mapAvailablePoints = newMapPoints();
	static int mapIndex = 0;
	
	private static int[] nextPos() {
		if (mapAvailablePoints.isEmpty()) { // 当前地图点已用完，需开辟新地图
			mapAvailablePoints = newMapPoints();
			mapIndex++;
		}
		int index = CommonUtils.randomInt(mapAvailablePoints.size());
		int x = mapAvailablePoints.remove(index);
		return new int[] { mapIndex, x, 0 };
	}
	
	
}
